﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms; using Montana.Entidades;
using Montana.Reportes;
using CrystalDecisions.Shared;

namespace Montana
{
    public partial class frmRecibo : Form
    {
        public frmRecibo()
        {
            InitializeComponent();
        }

        private void frmRecibo_Load(object sender, EventArgs e)
        {
            CargarColumnasDocumentosPendientes();
            CargarColumnasDocumentosCancelar();
            CargarColumnasResago();
            CargarColumnasCheque();

            txtFecha.Text = DateTime.Now.ToShortDateString();

            Cliente cli = new Cliente();
            cli.CargarCombo(cboCliente, true);
        }

        private void txtCodigoCliente_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                e.Handled = true;

                if (txtCodigoCliente.Text == "")
                {
                    Limpiar();
                    return;
                }

                Cliente cli = new Cliente();

                List<Cliente> items = cli.BuscarPorCodigo(txtCodigoCliente.Text);

                if (items.Count == 0)
                {
                    Limpiar();
                    return;
                }

                cboCliente.SelectedValue = items[0].ID.ToString();

                //txtCodigoProducto.Focus();
            }
        }

        private void Limpiar()
        {
            lswPendiente.Items.Clear();
            lswCancelar.Items.Clear();

            lswCheque.Items.Clear();
            lswResago.Items.Clear();

            txtEfectivoEntregado.Text = "";
            
            CalcularTotales();
        }

        private void cboCliente_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;

            if (cboCliente.Text == "")
            {
                Limpiar();
                this.Cursor = Cursors.Default;
                return;
            }

            Cliente cli = new Cliente();
            cli = cli.BuscarPorID((int)cboCliente.SelectedValue);

            //txtSaldoAnterior.Text = cli.Saldo.ToString("0.00");
            txtSaldoAnterior.Text = ObtenerSaldo(cli.ID, cli.Saldo);

            CargarDocumentosPendientes(cli.ID);

            this.Cursor = Cursors.Default;
        }

        private string ObtenerSaldo(int idCliente, decimal saldoInicial)
        {
            Factura fac = new Factura();
            List<Factura> facturas = fac.BuscarPendientesBlanco(idCliente);
          
            foreach (Factura f in facturas)
            {
                decimal importeTotal = f.Importetotal - (f.Importetotal * f.Porcentajebonificacion / 100);
                importeTotal += f.Importeiva;
                
                saldoInicial += importeTotal - f.Importecancelado;
            }

            return saldoInicial.ToString("0.00");
        }

        private void btnCerrar_Click(object sender, EventArgs e)
        {
            this.Close();
        }


        private void btnAgregarCheque_Click(object sender, EventArgs e)
        {
            if (!ValidarCheque())
                return;

            decimal importe = Validacion.ValDecimal(txtImporteCheque);

            AgregarCheque(txtBanco.Text, txtNumeroCheque.Text, txtFechaDeposito.Text, importe, chkChequeEsContable.Checked);

            txtBanco.Focus();

            CalcularTotales();
        }

        private void CalcularTotales()
        {
            decimal total = 0;

            foreach (ListViewItem item in lswCancelar.Items)
                total += decimal.Parse(item.SubItems[5].Text);

            txtTotal.Text = total.ToString("0.00");

            total = Validacion.ValDecimal(txtEfectivoEntregado);

            foreach (ListViewItem item in lswCheque.Items)
                total += Validacion.ValDecimal(item.SubItems[3]);

            foreach (ListViewItem item in lswResago.Items)
                total += Validacion.ValDecimal(item.SubItems[3]);

            txtTotalEntregado.Text = total.ToString("0.00");

            //Validacion.ValDecimal(txtTotal)
            decimal nuevoSaldo = (-1 * total) + Validacion.ValDecimal(txtSaldoAnterior);
            txtNuevoSaldo.Text = nuevoSaldo.ToString("0.00");
        }

        private void AgregarCheque(string banco, string numeroCheque, string fechaDeposito, decimal importe, bool esContable)
        {
            lswCheque.Items.Add(banco);
            lswCheque.Items[lswCheque.Items.Count - 1].SubItems.Add(numeroCheque);
            lswCheque.Items[lswCheque.Items.Count - 1].SubItems.Add(fechaDeposito);
            lswCheque.Items[lswCheque.Items.Count - 1].SubItems.Add(importe.ToString("0.00"));
            lswCheque.Items[lswCheque.Items.Count - 1].SubItems.Add(esContable ? "Si" : "No");
        }

        private bool ValidarCheque()
        {
            if (Validacion.EstaVacio(txtBanco, "Debe ingresar el banco"))
                return false;

            if (Validacion.EstaVacio(txtNumeroCheque, "Debe ingresar el número"))
                return false;

            if (Validacion.EstaVacio(txtFechaDeposito, "Debe ingresar la fecha"))
                return false;

            if (Validacion.ValFecha(txtFechaDeposito, "La fecha es incorrecta"))
                return false;

            return true;
        }

        private void btnQuitarCheque_Click(object sender, EventArgs e)
        {
            if (lswCheque.SelectedItems.Count == 0)
                return;

            lswCheque.SelectedItems[0].Remove();

            CalcularTotales();
        }

        private void btnAgregarResago_Click(object sender, EventArgs e)
        {
            if (!ValidarResago())
                return;

            decimal precio = Validacion.ValDecimal(txtPrecioResago);
            decimal kilos = Validacion.ValDecimal(txtKilosResagos);
            decimal subtotal = precio * kilos;

            AgregarResago(txtDescripcionResago.Text, kilos, precio, subtotal, chkResagoEsContable.Checked);

            txtDescripcionResago.Focus();

            CalcularTotales();
        }

        private void AgregarResago(string descripcion, decimal kilos, decimal precio, decimal subtotal, bool esContable)
        {
            lswResago.Items.Add(descripcion);
            lswResago.Items[lswResago.Items.Count - 1].SubItems.Add(kilos.ToString("0.00"));
            lswResago.Items[lswResago.Items.Count - 1].SubItems.Add(precio.ToString("0.00"));
            lswResago.Items[lswResago.Items.Count - 1].SubItems.Add(subtotal.ToString("0.00"));
            lswResago.Items[lswResago.Items.Count - 1].SubItems.Add(esContable ? "Si" : "No");
        }

        private bool ValidarResago()
        {
            if (Validacion.EstaVacio(txtDescripcionResago, "Debe ingresar la descripción"))
                return false;

            if (Validacion.EstaVacio(txtKilosResagos, "Debe ingresar los kilos"))
                return false;

            if (Validacion.EstaVacio(txtPrecioResago, "Debe ingresar el precio"))
                return false;

            return true;
        }

        private void btnQuitarResago_Click(object sender, EventArgs e)
        {
            if (lswResago.SelectedItems.Count == 0)
                return;

            lswResago.SelectedItems[0].Remove();

            CalcularTotales();
        }

        private void CargarColumnasDocumentosPendientes()
        {
            lswPendiente.Columns.Add("Fecha", 80);
            lswPendiente.Columns.Add("Documento", 110);
            lswPendiente.Columns.Add("Importe", 75, HorizontalAlignment.Right);
            lswPendiente.Columns.Add("Cancelado", 75, HorizontalAlignment.Right);
            lswPendiente.Columns.Add("Saldo", 75, HorizontalAlignment.Right);
        }

        private void CargarDocumentosPendientes(int idCliente)
        {
            Factura fac = new Factura();
            List<Factura> facturas = fac.BuscarPendientesBlanco(idCliente);

            lswPendiente.Items.Clear();
            foreach (Factura f in facturas)
            {
                decimal importeTotal = f.Importetotal - (f.Importetotal * f.Porcentajebonificacion / 100);
                importeTotal += f.Importeiva;

                decimal saldo = importeTotal - f.Importecancelado;
                if (saldo == 0)
                    continue;

                ListViewItem item = lswPendiente.Items.Add(f.Fecha.ToShortDateString());
                item.Tag = f;
                item.SubItems.Add("FC " + f.Letra + " " + f.Nombre);
                item.SubItems.Add(importeTotal.ToString("0.00"));
                item.SubItems.Add(f.Importecancelado.ToString("0.00"));                
                item.SubItems.Add(saldo.ToString("0.00"));
            }
        }

        private void CargarColumnasDocumentosCancelar()
        {
            lswCancelar.Columns.Add("Fecha", 80);
            lswCancelar.Columns.Add("Documento", 110);
            lswCancelar.Columns.Add("Importe", 75, HorizontalAlignment.Right);
            lswCancelar.Columns.Add("Cancelado", 75, HorizontalAlignment.Right);
            lswCancelar.Columns.Add("Saldo", 75, HorizontalAlignment.Right);
            lswCancelar.Columns.Add("Cancela", 75, HorizontalAlignment.Right);
        }

        private void btnAgregar_Click(object sender, EventArgs e)
        {
            if (lswPendiente.SelectedItems.Count == 0)
                return;
            
            foreach (ListViewItem it in lswCancelar.Items)
            {
                if (lswPendiente.SelectedItems[0].SubItems[1].Text == it.SubItems[1].Text)
                {
                    Validacion.MostrarError(lswPendiente, "El documento ya fue ingresado");
                    return;
                }
            }

            Factura f = (Factura)lswPendiente.SelectedItems[0].Tag;
            decimal saldo = decimal.Parse(lswPendiente.SelectedItems[0].SubItems[4].Text);

            frmInputBox frm = new frmInputBox("Recibos", "Ingrese el importe a cancelar (máximo " + saldo.ToString() + ")");

            decimal cancela = 9999999;
            while (cancela > saldo)
            {
                frm.ShowDialog();
                if (frm.DialogResult == DialogResult.Cancel)
                    return;

                cancela = Validacion.ValDecimal(frm.Valor);
                f.Importecancelado = cancela;
            }            

            ListViewItem item = lswCancelar.Items.Add(f.Fecha.ToShortDateString());
            item.Tag = f;

            item.SubItems.Add(f.Tipo + " " + f.Letra + " " + f.Nombre);
            item.SubItems.Add(f.Importetotal.ToString("0.00"));
            item.SubItems.Add(f.Importecancelado.ToString("0.00"));            
            item.SubItems.Add(saldo.ToString("0.00"));
            item.SubItems.Add(cancela.ToString("0.00"));

            CalcularTotales();
        }

        private void btnQuitar_Click(object sender, EventArgs e)
        {
            if (lswCancelar.SelectedItems.Count == 0)
                return;

            lswCancelar.SelectedItems[0].Remove();

            CalcularTotales();
        }

        private void txtEfectivoEntregado_TextChanged(object sender, EventArgs e)
        {
            CalcularTotales();
        }

        private void CargarColumnasResago()
        {
            lswResago.Columns.Add("Descripción", 100);
            lswResago.Columns.Add("Kilos", 60, HorizontalAlignment.Right);
            lswResago.Columns.Add("Precio X Kilo", 90, HorizontalAlignment.Right);
            lswResago.Columns.Add("Subtotal", 70, HorizontalAlignment.Right);
            lswResago.Columns.Add("Contable", 80);
        }

        private void CargarColumnasCheque()
        {
            lswCheque.Columns.Add("Banco", 100);
            lswCheque.Columns.Add("Número", 100);
            lswCheque.Columns.Add("Fecha Dep.", 80);
            lswCheque.Columns.Add("Importe", 90, HorizontalAlignment.Right);
            lswCheque.Columns.Add("Contable", 80);
        }

        private List<Resago> ArmarResagos(ref decimal totalResagos)
        {
            List<Resago> resagos = new List<Resago>();

            foreach (ListViewItem item in lswResago.Items)
            {
                Resago r = new Resago();

                r.Nombre = item.Text;
                r.Kilos = Validacion.ValDecimal(item.SubItems[1]);
                r.Preciokilo = Validacion.ValDecimal(item.SubItems[2]);
                r.Escontable = chkResagoEsContable.Checked ? "S" : "N";

                totalResagos += r.Kilos * r.Preciokilo;

                resagos.Add(r);
            }

            return resagos;
        }

        private List<Cheque> ArmarCheques(ref decimal totalCheques)
        {
            List<Cheque> cheques = new List<Cheque>();

            foreach (ListViewItem item in lswCheque.Items)
            {
                Cheque c = new Cheque();

                c.Banco = item.Text;
                c.Nombre = item.SubItems[1].Text;
                c.Fechadeposito = Validacion.ValFecha(item.SubItems[2]);
                c.Importe = Validacion.ValDecimal(item.SubItems[3]);
                c.Escontable = chkChequeEsContable.Checked ? "S" : "N";

                totalCheques += c.Importe;

                cheques.Add(c);
            }

            return cheques;
        }

        private List<IDocumento> ArmarDocumentosCancelados()
        {
            List<IDocumento> documentos = new List<IDocumento>();

            foreach (ListViewItem item in lswCancelar.Items)
                documentos.Add((IDocumento)item.Tag);

            return documentos;
        }

        private Recibo ArmarRecibo(decimal totalCheques, decimal totalResagos)
        {
            Recibo rec = new Recibo();

            rec.Fecha = Validacion.ValFecha(txtFecha);
            rec.IDCliente = Validacion.GetValue(cboCliente);
            rec.Importeefectivo = Validacion.ValDecimal(txtEfectivoEntregado);
            rec.Importecheques = totalCheques;
            rec.Importeresagos = totalResagos;
            rec.Total = Validacion.ValDecimal(txtTotal);
            rec.Saldoanterior = Validacion.ValDecimal(txtSaldoAnterior);
            rec.Saldonuevo = Validacion.ValDecimal(txtNuevoSaldo);

            return rec;
        }

        private void btnGuardar_Click(object sender, EventArgs e)
        {
            decimal totalCheques = 0, totalResagos = 0;

            List<Cheque> cheques = ArmarCheques(ref totalCheques);
            List<Resago> resagos = ArmarResagos(ref totalResagos);
            List<IDocumento> documentos = ArmarDocumentosCancelados();

            Recibo rec = ArmarRecibo(totalCheques, totalResagos);

            this.Tag = rec.NuevoRecibo(cheques, resagos, documentos);

            Limpiar();

            Validacion.MostrarMensaje("El recibo fue guardado");

            btnImprimir.Enabled = true;
            btnGuardar.Enabled = false;
        }

        private void frmRecibo_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
                    btnCerrar_Click(this, null);
                    break;
                case Keys.F1:
                    btnGuardar_Click(this, null);
                    break;
                case Keys.F2:
                    btnImprimir_Click(this, null);
                    break;
                case Keys.F9:
                    txtEfectivoEntregado.Focus();
                    break;
                case Keys.F10:
                    txtBanco.Focus();
                    break;
                case Keys.F11:
                    txtDescripcionResago.Focus();
                    break;

            }
        }

        private void btnImprimir_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;

            Reporte r = new Reporte();
            rptRecibo recibo = new rptRecibo();
            DataSet ds = new DataSet();

            Recibo rec = new Recibo();
            int idRecibo = (int)this.Tag;

            rec.ReporteRecibo(ds, idRecibo);

            string selectionFormula = "{Recibo.ID}=" + idRecibo;

            ParameterFields parametros = new ParameterFields();

            //r.Formulas.Add("OcultarEfectivo", "S");

            r.MostrarReporte(ds, recibo, selectionFormula, parametros);

            this.Cursor = Cursors.Default;
        }

        private void btnNuevo_Click(object sender, EventArgs e)
        {
            cboCliente.SelectedIndex = 0;
            Limpiar();

            btnGuardar.Enabled = true;
            btnImprimir.Enabled = false;
        }

        private void btnBuscarFactura_Click(object sender, EventArgs e)
        {
            frmBuscarRecibo frm = new frmBuscarRecibo();

            frm.ShowDialog();

            if (frm.ReciboSeleccionado == null)
                return;

            CargarRecibo(frm.ReciboSeleccionado);
        }

        private void CargarRecibo(Recibo recibo)
        {
            txtNumeroRecibo.Text = recibo.NumeroRecibo;
            txtFecha.Text = recibo.Fecha.ToShortDateString();
            cboCliente.SelectedValue = recibo.IDCliente.ToString();
            lswPendiente.Items.Clear();
            this.Tag = recibo.ID;

            txtEfectivoEntregado.Text = recibo.Importeefectivo.ToString("0.00");

            Cheque che = new Cheque();
            CargarCheques(che.BuscarPorIDRecibo(recibo.ID));

            Resago res = new Resago();
            CargarResagos(res.BuscarPorIDRecibo(recibo.ID));

            ReciboDocumento rec = new ReciboDocumento();
            CargarDocumentos(rec.BuscarDocumentosPorRecibo(recibo.ID));

            CalcularTotales();

            btnGuardar.Enabled = false;
            btnImprimir.Enabled = true;
        }

        private void CargarDocumentos(List<ReciboDocumento> documentos)
        {
            decimal totalCancelado = 0;

            lswCancelar.Items.Clear();
            foreach (ReciboDocumento d in documentos)
            {
                ListViewItem item = lswCancelar.Items.Add(d.Fecha.ToShortDateString());
                item.Tag = d;

                item.SubItems.Add("FC " + d.Letra + " " + d.Nombre);
                item.SubItems.Add(d.Importetotal.ToString("0.00"));
                item.SubItems.Add(d.Importecancelado.ToString("0.00"));
                item.SubItems.Add(d.Saldo.ToString("0.00"));
                item.SubItems.Add(d.Cancela.ToString("0.00"));

                totalCancelado += d.Cancela;
            }

            txtTotal.Text = totalCancelado.ToString("0.00");
        }

        private void CargarCheques(List<Cheque> cheques)
        {
            lswCheque.Items.Clear();
            foreach (var c in cheques)
            {
                AgregarCheque(c.Banco, c.Nombre, c.Fechadeposito.ToShortDateString(), c.Importe, c.Escontable == "S" ? true : false);
            }
        }

        private void CargarResagos(List<Resago> resagos)
        {
            lswResago.Items.Clear();
            foreach (var r in resagos)
            {
                AgregarResago(r.Nombre, r.Kilos, r.Preciokilo, r.Kilos * r.Preciokilo, r.Escontable == "S" ? true : false);
            }
        }
    }
}
